<template>
  <a-row>
    <a-button style="float: right" type="primary" @click="showDrawer"
      >字段联动</a-button
    >
    <a-drawer
      placement="right"
      :closable="false"
      :visible="visible"
      :width="700"
      :mask-closable="true"
      @after-visible-change="afterVisibleChange"
      @close="onClose"
    >
      <template #title>
        <span>字段联动</span>
        <a-button style="float: right" type="primary" @click="genRule"
          >生成规则</a-button
        >
        <a-button
          style="float: right; margin-right: 10px"
          status="success"
          @click="onClose"
          >取消</a-button
        >
      </template>
      <a-row>
        <a-select
          v-model="selectedField"
          style="min-width: 30%"
          placeholder="请选择"
        >
          <a-option
            v-for="item in linkList"
            :key="item.dataIndex"
            :value="item.dataIndex"
            >{{ item.name }}</a-option
          >
        </a-select>
        <a-button @click.stop="copyLinkageConfig">复制联动</a-button>
      </a-row>

      <a-divider></a-divider>
      <a-form :model="linkageConfig" ref="form">
        <a-row>
          <a-col>
            <a-button
              type="primary"
              style="margin-bottom: 20px"
              :disabled="['checkbox', 'editor'].includes(formData.type)"
              @click="handleDataAdd"
              >新增数据联动</a-button
            >
          </a-col>
          <a-col
            v-for="(config, index) in linkageConfig.dataConfig"
            :key="config.cid"
          >
            <a-form-item style="height: 5px">
              <a-checkbox v-model="config.firstTrigger"
                >首次进入触发</a-checkbox
              >
            </a-form-item>
            <a-form-item style="display: inline-block"
              >当此字段值改变时请求</a-form-item
            >
            <a-form-item style="display: inline-block; margin-left: 5px">
              <a-select
                v-model="config.plugInfo.componentType"
                show-search
                allow-clear
                placeholder="请选择类型"
                :filter-option="filterOption"
                style="min-width: 100px"
                @change="onChange(index)"
              >
                <a-option
                  v-for="option in plugTypeList"
                  :key="option.value"
                  :value="option.value"
                  >{{ option.label }}</a-option
                >
              </a-select>
            </a-form-item>
            <a-form-item
              style="margin-left: 5px; display: inline-block"
              :field="`dataConfig.${index}.plugInfo.dataId`"
              :rules="rules.dataId"
              v-if="config.plugInfo.componentType === 'dataSource'"
            >
              <a-select
                v-model="config.plugInfo.dataId"
                show-search
                allow-clear
                placeholder="请选择流程"
                :filter-option="filterOption"
                style="min-width: 150px"
                @change="onChange(index)"
              >
                <a-option
                  v-for="item in dataSourceList"
                  :key="item.dataId"
                  :value="item.dataId"
                  :title="item.dataName"
                >
                  {{ item.dataName }}
                </a-option>
              </a-select>
            </a-form-item>
            <a-form-item
              style="margin-left: 5px; display: inline-block"
              :field="`dataConfig.${index}.plugInfo.plugId`"
              :rules="rules.plugId"
              v-else-if="config.plugInfo.componentType === 'plug'"
            >
              <a-select
                v-model="config.plugInfo.plugId"
                show-search
                allow-clear
                placeholder="请选择插件"
                :filter-option="filterOption"
                style="min-width: 150px"
                @change="onChange(index)"
              >
                <a-option
                  v-for="option in plugList"
                  :key="option.plugId"
                  :value="option.plugId"
                  >{{ option.plugName }}</a-option
                >
              </a-select>
            </a-form-item>

            <a-form-item style="display: inline-block; margin-left: 5px">
              <a-button type="primary" @click="handleEditPlug(index)"
                >编辑</a-button
              >
            </a-form-item>
            <a-form-item style="display: inline-block">
              <icon-minus-circle
                style="margin-left: 5px"
                @click="handleDeleteDataItem(config)"
              />
            </a-form-item>
          </a-col>
        </a-row>
        <plug-in-config
          ref="plugInConfig"
          :data-config="this.linkageConfig.dataConfig"
        ></plug-in-config>

        <a-divider></a-divider>

        <a-row>
          <a-button
            type="primary"
            style="margin-bottom: 20px"
            @click="handleAdd"
            >新增组件展示逻辑</a-button
          >
        </a-row>
        <a-row
          v-for="(option, index) in linkageConfig.fieldConfig"
          :key="index"
        >
          <a-col>
            <a-form-item style="display: inline-block">当&nbsp;</a-form-item>
            <a-form-item
              style="display: inline-block; min-width: 120px"
              :field="`fieldConfig.${index}.field`"
              :rules="rules.field"
            >
              <a-select v-model="option.field">
                <a-option
                  v-for="item in nameList"
                  :key="item.dataIndex"
                  :value="item.dataIndex"
                  >{{ item.name }}</a-option
                >
              </a-select>
            </a-form-item>
            <a-form-item
              style="display: inline-block; margin: 0 5px; min-width: 80px"
            >
              <a-select v-model="option.fieldValueType">
                <a-option
                  v-for="item in fieldValueTypeList"
                  :key="item.value"
                  :value="item.value"
                  >{{ item.label }}</a-option
                >
              </a-select>
            </a-form-item>
            <!--            <a-form-item style="display: inline-block" v-if="option.fieldValueType !== 'notEmpty'">&nbsp;值为&nbsp;</a-form-item>-->
            <a-form-item
              style="display: inline-block"
              :field="`fieldConfig.${index}.fieldValue`"
              :rules="rules.fieldValue"
              v-if="option.fieldValueType !== 'notEmpty'"
            >
              <a-input
                placeholder="请输入值"
                v-model="option.fieldValue"
              ></a-input>
            </a-form-item>
            <a-form-item style="display: inline-block"
              >&nbsp;时展示该控件</a-form-item
            >
            <a-form-item style="display: inline-block">
              <icon-minus-circle
                style="margin-left: 5px"
                @click="handleDeleteItem(index)"
              />
            </a-form-item>
          </a-col>
          <a-col
            style="margin-top: -30px"
            v-if="
              linkageConfig.fieldConfig.length > 1 &&
              index !== linkageConfig.fieldConfig.length - 1
            "
          >
            <a-tag
              :color="option.logical === '&&' ? '#108ee9' : ''"
              @click="option.logical = '&&'"
              >并且</a-tag
            >
            <a-tag
              :color="option.logical === '||' ? '#108ee9' : ''"
              @click="option.logical = '||'"
              >或</a-tag
            >
          </a-col>
        </a-row>
        <div v-if="false">
          <a-divider></a-divider>
          <a-row>
            <a-button
              type="primary"
              style="margin-bottom: 20px"
              @click="handleclearAdd"
              >新增组件值清空逻辑</a-button
            >
          </a-row>
          <a-row
            v-for="(option, index) in linkageConfig.clearConfig"
            :key="index"
          >
            <a-col>
              <a-form-item style="display: inline-block">当&nbsp;</a-form-item>
              <a-form-item
                style="display: inline-block; min-width: 120px"
                :field="`clearConfig.${index}.field`"
                :rules="rules.field"
              >
                <a-select v-model="option.field">
                  <a-option
                    v-for="item in nameList"
                    :key="item.dataIndex"
                    :value="item.dataIndex"
                    >{{ item.name }}</a-option
                  >
                </a-select>
              </a-form-item>
              <a-form-item
                style="display: inline-block; margin: 0 5px; min-width: 80px"
              >
                <a-select v-model="option.fieldValueType">
                  <a-option
                    v-for="item in fieldValueTypeList"
                    :key="item.value"
                    :value="item.value"
                    >{{ item.label }}</a-option
                  >
                </a-select>
              </a-form-item>
              <!--            <a-form-item style="display: inline-block" v-if="option.fieldValueType !== 'notEmpty'">&nbsp;值为&nbsp;</a-form-item>-->
              <a-form-item
                style="display: inline-block"
                :field="`clearConfig.${index}.fieldValue`"
                :rules="rules.fieldValue"
                v-if="option.fieldValueType !== 'notEmpty'"
              >
                <a-input
                  placeholder="请输入值"
                  v-model="option.fieldValue"
                ></a-input>
              </a-form-item>
              <a-form-item style="display: inline-block"
                >&nbsp;时清空该控件值</a-form-item
              >
              <a-form-item style="display: inline-block">
                <icon-minus-circle
                  style="margin-left: 5px"
                  @click="clearConfigDeleteItem(index)"
                />
              </a-form-item>
            </a-col>
            <a-col
              style="margin-top: -30px"
              v-if="
                linkageConfig.clearConfig.length > 1 &&
                index !== linkageConfig.clearConfig.length - 1
              "
            >
              <a-tag
                :color="option.logical === '&&' ? '#108ee9' : ''"
                @click="option.logical = '&&'"
                >并且</a-tag
              >
              <a-tag
                :color="option.logical === '||' ? '#108ee9' : ''"
                @click="option.logical = '||'"
                >或</a-tag
              >
            </a-col>
          </a-row>
        </div>
      </a-form>
    </a-drawer>
  </a-row>
</template>

<script>
import _ from "lodash";
import PlugInConfig from "@/components/Form/base/plugInConfig.vue";
import { nanoid } from "nanoid";
import { parseShowRulesToStr } from "@/mixins/methodsMixins";
import { post } from "@/utils/request";

export default {
  name: "FieldLinkage",
  components: { PlugInConfig },
  props: {
    formData: {
      type: Object,
      default: () => ({}),
    },
    dataShowFieldOptions: {
      type: Array,
      default: () => [],
    },
  },
  computed: {
    nameList() {
      const appendList = [
        {
          name: "变量：$" + "{level}",
          dataIndex: "$" + "{level}",
        },
      ];
      return this.dataObj.pageData
        .concat(this.dataObj.defaultKeys)
        .filter((item) => item.formData.dataIndex !== this.formData.dataIndex)
        .map((item) => {
          return {
            name: item.formData.name,
            dataIndex: item.formData.dataIndex,
          };
        })
        .concat(appendList);
    },
    linkList() {
      return this.dataObj.pageData
        .filter((item) => !_.isEmpty(item.formData.linkageConfig))
        .map((item) => {
          return {
            name: item.formData.name,
            dataIndex: item.formData.dataIndex,
            linkageConfig: item.formData.linkageConfig,
          };
        });
    },
  },
  data() {
    return {
      dataSourceList: [], // 所有数据源列表
      // dataShowFieldOptions: [],
      // dataCondition: [],
      fieldValueTypeList: [
        { label: "等于", value: "fixed" },
        { label: "不等于", value: "unequal" },
        { label: "不为空", value: "notEmpty" },
        { label: "小于", value: "lt" }, // fangyan
        { label: "大于", value: "jt" }, // fangyan
      ],
      rules: {
        plugId: [{ required: true, message: "必填" }],
        dataId: [{ required: true, message: "必填" }],
        field: [{ required: true, message: "必填" }],
        fieldValue: [{ required: true, message: "必填" }],
      },
      linkageConfig: {
        dataConfig: [],
        fieldConfig: [],
        clearConfig: [],
      },
      plugTypeList: [
        { label: "插件", value: "plug" },
        { label: "数据源", value: "dataSource" },
        { label: "选项出参", value: "optionsOutParam" },
      ],
      plugList: [], // 所有插件列表
      selectedField: undefined, // 选择的规则对象
      visible: false,
    };
  },
  inject: ["dataObj"],
  methods: {
    // 选择了数据源，需要查询有哪些展示字段
    async queryDataSourceDetails(dataId) {
      console.log(dataId, "dataIddataId");
      try {
        const result = await this.$http.get(
          "/datasource/queryDataSourceDetail",
          {
            params: {
              dataId,
            },
          }
        );
        const { data } = result;
        const {
          dataColumnQueryDTOList,
          aggregateFunctionInfoReqDTO,
          dataSourceQueryDTO,
          queryGroupReqDTOList,
        } = data;
        const { aggregateFunctionInfoAddDTOList } =
          aggregateFunctionInfoReqDTO || {};
        const mergedList = dataColumnQueryDTOList.concat(
          aggregateFunctionInfoAddDTOList || []
        );
        const resultData = {
          plugParamIODTO: {
            controlTypeObj: {},
            outputParam: {},
            inputParam: {},
            allParamInfo: {},
          },
          dataName: dataSourceQueryDTO.dataName,
        };
        // 需要根据columnKey去重后的对象数组，而不是单纯的columnKey集合，可以进一步处理： 作为出参
        // eslint-disable-next-line no-return-assign
        mergedList.forEach(
          (item) => (resultData.plugParamIODTO.outputParam[item.columnAs] = "")
        );
        // 入参
        console.log(queryGroupReqDTOList);
        // eslint-disable-next-line no-unused-expressions
        queryGroupReqDTOList?.forEach((item) => {
          const { tableQueryGroupAddDTOList } = item;
          tableQueryGroupAddDTOList.forEach((item) => {
            const { queryKey, groupId, between } = item;
            if (_.isArray(between) && between.length) {
              resultData.plugParamIODTO.inputParam[
                groupId + between[0].queryKey
              ] = "";
              resultData.plugParamIODTO.inputParam[
                groupId + between[1].queryKey
              ] = "";
              resultData.plugParamIODTO.controlTypeObj[
                groupId + between[0].queryKey
              ] = "";
              resultData.plugParamIODTO.controlTypeObj[
                groupId + between[1].queryKey
              ] = "";
              resultData.plugParamIODTO.allParamInfo[
                groupId + between[0].queryKey
              ] = item;
              resultData.plugParamIODTO.allParamInfo[
                groupId + between[1].queryKey
              ] = item;
              return;
            }
            if (queryKey) {
              resultData.plugParamIODTO.inputParam[groupId + queryKey] = "";
              resultData.plugParamIODTO.controlTypeObj[groupId + queryKey] = "";
              console.log(
                groupId + queryKey,
                resultData.plugParamIODTO.controlTypeObj,
                "查询"
              );
              resultData.plugParamIODTO.allParamInfo[groupId + queryKey] = item;
            }
          });
        });
        return resultData;
      } catch (e) {
        console.error("请求失败", e);
      }
    },
    // 查询数据源列表
    async queryDatasourceList(dataName) {
      // try {
      //   const result = await post(`/datasource/querySourceAllList`, {
      //     dataTypeList: ["select", "selTable", "report", "interface"],
      //     dataName: dataName || "",
      //   });
      //   const { data } = result;
      //   this.dataSourceList = data;
      // } catch (e) {
      //   console.error("请求失败", e);
      // }
    },
    // 切换插件
    onChange(index) {
      Object.assign(this.linkageConfig.dataConfig[index].plugInfo, {
        plugParamIODTO: {},
      });
    },
    // 编辑插件映射关系
    async handleEditPlug(index) {
      const {
        plugParamIODTO: oldPlugParamIODTO,
        componentType,
        dataId,
        plugId,
      } = this.linkageConfig.dataConfig[index].plugInfo;
      if (componentType === "dataSource") {
        const { dataName, plugParamIODTO } =
          await this.queryDataSourceDetails(dataId);
        plugParamIODTO.controlTypeObj = oldPlugParamIODTO.controlTypeObj || {};
        // eslint-disable-next-line no-return-assign
        Object.keys(plugParamIODTO?.inputParam || {}).forEach((key) => {
          if (oldPlugParamIODTO?.inputParam?.[key]) {
            plugParamIODTO.inputParam[key] = oldPlugParamIODTO.inputParam[key];
          }
        });
        Object.keys(plugParamIODTO?.outputParam || {}).forEach((key) => {
          if (oldPlugParamIODTO?.outputParam?.[key]) {
            plugParamIODTO.outputParam[key] =
              oldPlugParamIODTO.outputParam[key];
          }
        });
        this.linkageConfig.dataConfig[index].plugInfo.plugParamIODTO =
          plugParamIODTO;
        this.linkageConfig.dataConfig[index].plugInfo.dataName = dataName;
        this.linkageConfig.dataConfig[index].plugInfo.componentType =
          componentType;
        console.log(
          this.linkageConfig.dataConfig,
          "this.linkageConfig.dataConfig"
        );
      } else if (componentType === "plug") {
        const [info] = await this.getPlugInfo(plugId);
        const plugParamIODTO = info.plugParamIODTO;
        // eslint-disable-next-line no-return-assign
        info.plugParamIODTO.controlTypeObj =
          oldPlugParamIODTO.controlTypeObj ||
          _.mapValues(info.plugParamIODTO.inputParam, (value) => "") ||
          {};

        Object.keys(plugParamIODTO?.inputParam || {}).forEach((key) => {
          if (oldPlugParamIODTO?.inputParam?.[key]) {
            plugParamIODTO.inputParam[key] = oldPlugParamIODTO.inputParam[key];
          }
        });
        Object.keys(plugParamIODTO?.outputParam || {}).forEach((key) => {
          if (oldPlugParamIODTO?.outputParam?.[key]) {
            plugParamIODTO.outputParam[key] =
              oldPlugParamIODTO.outputParam[key];
          }
        });
        info.componentType = componentType;

        // eslint-disable-next-line no-return-assign
        this.linkageConfig.dataConfig[index].plugInfo = info;
      } else {
        console.log(this.dataShowFieldOptions, "查看展示字段");
        const outputParam = {};
        this.dataShowFieldOptions.map((item) => {
          outputParam[item.columnAs] =
            oldPlugParamIODTO?.outputParam?.[item.columnAs] || "";
        });
        // this.linkageConfig.dataConfig[index].plugInfo = {}
        this.linkageConfig.dataConfig[index].plugInfo.dataId = "";
        this.linkageConfig.dataConfig[index].plugInfo.plugId = "";
        this.linkageConfig.dataConfig[index].plugInfo.plugParamIODTO = {
          controlTypeObj: {},
          outputParam: outputParam,
          inputParam: {},
        };
      }
      await this.$refs["plugInConfig"].open(index);
    },
    // 获取插件ID的映射关系
    async getPlugInfo(plugId) {
      try {
        const result = await post(`/pluginfo/queryByPlugIdList`, {
          plugIdList: [plugId],
        });
        return result.data;
      } catch (e) {
        console.error(e);
      }
    },
    // 下拉框按label搜索
    filterOption(input, option) {
      return (
        option.componentOptions.children[0].text
          .toLowerCase()
          .indexOf(input.toLowerCase()) >= 0
      );
    },
    // 获取所有插件列表
    async getPlugList() {
      const plugInfoListQueryDTO = {
        pageNo: 1,
        pageSize: 11110,
        plugEffectType: [],
        plugName: "",
        plugType: "exec",
      };
      // const result = await post(`/pluginfo/list`, {
      //   plugInfoListQueryDTO,
      // });
      // this.plugList = result.data;
    },
    // 复制联动数据
    copyLinkageConfig() {
      const config = this.linkList.find(
        (item) => this.selectedField === item.dataIndex
      );
      Object.assign(this.linkageConfig, config.linkageConfig);
    },
    // 删除字段联动
    handleDeleteItem(index) {
      this.linkageConfig.fieldConfig.splice(index, 1);
    },
    // 删除字段清空
    clearConfigDeleteItem(index) {
      this.linkageConfig.clearConfig.splice(index, 1);
    },
    // 删除数据联动
    handleDeleteDataItem(config) {
      const { cid } = config;
      const index = this.linkageConfig.dataConfig.findIndex(
        (item) => item.cid === cid
      );
      this.linkageConfig.dataConfig.splice(index, 1);
    },
    parseShowRulesToStr,
    // 生成规则
    genRule() {
      this.$refs.form.validate(async (valid) => {
        if (valid) {
          this.formData.fieldLinkage = this.parseShowRulesToStr(
            this.linkageConfig.fieldConfig
          );
          this.formData.clearConfig = this.parseShowRulesToStr(
            this.linkageConfig.clearConfig
          );
          this.formData.linkageConfig = _.cloneDeep(this.linkageConfig);
          console.log(
            "规则输出",
            this.formData.fieldLinkage,
            this.linkageConfig
          );
          this.$message.success("规则生成成功");
          this.onClose();
        } else {
          this.$message.warn("请检查填写内容");
        }
      });
    },
    // 新增规则
    handleAdd() {
      if (this.nameList.length === 0) {
        this.$message.error("无其它字段可联动");
        return;
      }
      const field = this.nameList[0].dataIndex;
      this.linkageConfig.fieldConfig.push({
        field,
        fieldValue: "",
        logical: "&&",
        fieldValueType: "fixed",
      });
    },
    // 新增清空规则
    handleclearAdd() {
      if (this.nameList.length === 0) {
        this.$message.error("无其它字段可联动");
        return;
      }
      const field = this.nameList[0].dataIndex;
      this.linkageConfig.clearConfig.push({
        field,
        fieldValue: "",
        logical: "&&",
        fieldValueType: "fixed",
      });
    },
    // 新增数据联动
    handleDataAdd() {
      // if (this.nameList.length === 0) {
      //   this.$message.error('无其它字段可联动')
      //   return
      // }
      // const field = this.nameList[0].dataIndex
      this.linkageConfig.dataConfig.push({
        cid: "change_" + nanoid(10),
        firstTrigger: false,
        plugInfo: {
          componentType: "plug",
          plugId: "", // 插件id
          dataId: "", // 数据源id
          plugParamIODTO: {},
        }, // 插件信息
      });
    },
    afterVisibleChange(val) {
      console.log("visible", val);
    },
    showDrawer() {
      const isOk = this.dataObj.pageData
        .filter((item) => item.isSendData)
        .every((item) => !!item.formData.dataIndex);
      if (!isOk) {
        this.$message.warn("请补充所有的数据绑定key");
        return;
      }
      const linkageConfig = _.cloneDeep(this.formData.linkageConfig);
      if (
        linkageConfig &&
        linkageConfig.fieldConfig &&
        Array.isArray(linkageConfig.fieldConfig)
      ) {
        linkageConfig.fieldConfig.forEach((item) => {
          if (!item.hasOwnProperty("fieldValueType")) {
            item.fieldValueType = "fixed"; // fieldValueType字段未有默认是fixed，这是兼容老数据
          }
        });
      }

      if (
        linkageConfig &&
        linkageConfig.clearConfig &&
        Array.isArray(linkageConfig.clearConfig)
      ) {
        linkageConfig.clearConfig.forEach((item) => {
          if (!item.hasOwnProperty("fieldValueType")) {
            item.fieldValueType = "fixed"; // fieldValueType字段未有默认是fixed，这是兼容老数据
          }
        });
      }

      if (
        linkageConfig &&
        !_.isArray(linkageConfig.dataConfig) &&
        !_.isEmpty(linkageConfig.dataConfig)
      ) {
        // 数组并且不为空
        linkageConfig.dataConfig.cid = "change_" + nanoid(10);
        linkageConfig.dataConfig = [linkageConfig.dataConfig];
      }
      // 这是兼容老数据，新增controlTypeObj
      // eslint-disable-next-line no-unused-expressions
      if (linkageConfig && !_.isEmpty(linkageConfig.dataConfig)) {
        linkageConfig.dataConfig.forEach((e) => {
          if (_.isEmpty(e.plugInfo.plugParamIODTO.controlTypeObj)) {
            e.plugInfo.plugParamIODTO.controlTypeObj = _.mapValues(
              e.plugInfo.plugParamIODTO.inputParam,
              (value) => ""
            );
          }
        });
      }

      Object.assign(this.linkageConfig, linkageConfig); // 赋值
      this.visible = true;
    },
    onClose() {
      this.visible = false;
    },
  },
  created() {
    this.getPlugList();
    this.queryDatasourceList();
  },
};
</script>

<style lang="less" scoped></style>
